<template>
  <div class="tui-dropdown" @keydown.esc="handleKeydown">
    <div ref="referenceEl" class="tui-dropdown__reference" :class="[disabledClass]" @click="handleReferenceClick" @contextmenu="handleContextmenu" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
      <slot></slot>
    </div>

    <teleport to="body">
      <div v-if="popperVisible" ref="popperEl" class="tui-dropdown__popper" :class="[popperClass, `tui-dropdown__popper--${placement}`, `tui-dropdown__popper--${size}`]" :style="popperStyle" @click="handlePopperClick" @mouseenter="handlePopperMouseEnter" @mouseleave="handlePopperMouseLeave">
        <div class="tui-dropdown__popper-content">
          <slot name="dropdown">
            <!-- 自定义实现下拉菜单项渲染 -->
            <div v-if="items && items.length > 0" class="tui-dropdown__menu">
              <template v-for="(item, index) in items" :key="item.name || item.label || `item-${index}`">
                <!-- 渲染分组标题 -->
                <div v-if="item.type === 'group'" class="tui-dropdown__menu-group-title">{{ item.title || item.label }}</div>
                <!-- 渲染菜单项 -->
                <div v-else-if="!item.children || item.children.length === 0" class="tui-dropdown__menu-item" :class="{ 'is-disabled': item.disabled }" @click="handleItemClick(item)" :disabled="item.disabled">
                  <tui-icon v-if="item.icon" :icon="item.icon" class="tui-dropdown__menu-item-icon" />
                  <span class="tui-dropdown__menu-item-label">{{ item.label || item.title || item.name }}</span>
                </div>
                <!-- 渲染子菜单 -->
                <div v-else class="tui-dropdown__submenu-wrapper">
                  <div class="tui-dropdown__submenu-title" @click="toggleSubmenu(index)">
                    <tui-icon v-if="item.icon" :icon="item.icon" class="tui-dropdown__menu-item-icon" />
                    <span class="tui-dropdown__menu-item-label">{{ item.label || item.title || item.name }}</span>
                    <tui-icon icon="tui:arrow-right" class="tui-dropdown__submenu-arrow" :class="{ 'is-expanded': expandedSubmenuIndex === index }" />
                  </div>
                  <div v-if="expandedSubmenuIndex === index" class="tui-dropdown__submenu">
                    <div v-for="(child, childIndex) in item.children" :key="child.name || child.label || `child-${childIndex}`" class="tui-dropdown__menu-item" :class="{ 'is-disabled': child.disabled }" @click="handleItemClick(child)" :disabled="child.disabled">
                      <tui-icon v-if="child.icon" :icon="child.icon" class="tui-dropdown__menu-item-icon" />
                      <span class="tui-dropdown__menu-item-label">{{ child.label || child.title || child.name }}</span>
                    </div>
                  </div>
                </div>
              </template>
            </div>
          </slot>
        </div>
      </div>
    </teleport>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue';
import { TuiDropdownProps, TuiDropdownItemData } from './types';

const props = withDefaults(defineProps<TuiDropdownProps>(), {
  trigger: 'hover',
  placement: 'bottom',
  showTimeout: 250,
  hideTimeout: 150,
  disabled: false,
  closeOnClickOutside: true,
  closeOnClickInside: false,
  popperOffset: 0,
  popperClass: '',
  showPopper: false,
  modelValue: false,
  items: () => [] as any[], // 菜单项数据
  activeIndex: '' // 当前激活的菜单项索引
});

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void;
  (e: 'show'): void;
  (e: 'hide'): void;
  (e: 'select', value: any): void;
  (e: 'visible-change', value: boolean): void;
}>();

// 引用元素
const referenceEl = ref<HTMLDivElement>();
const popperEl = ref<HTMLDivElement>();

// 状态管理
const popperVisible = ref(props.showPopper || props.modelValue);
const showTimer = ref<number>();
const hideTimer = ref<number>();
const isMounted = ref(false);
const expandedSubmenuIndex = ref<number | null>(null); // 用于跟踪展开的子菜单索引

// 计算属性
const disabledClass = computed(() => props.disabled ? 'tui-dropdown--disabled' : '');

const popperStyle = computed(() => {
  if (!referenceEl.value || !popperEl.value) return {};

  const referenceRect = referenceEl.value.getBoundingClientRect();
  const style: Record<string, string> = {};

  // 基本位置计算
  let top = 0;
  let left = 0;

  switch (props.placement) {
    case 'top':
      // 往上拉效果：让下拉菜单的顶部对齐于按钮顶部，菜单项向上延伸
      top = referenceRect.top - popperEl.value.offsetHeight - props.popperOffset;
      left = referenceRect.left + referenceRect.width / 2;
      style.transform = 'translate(-50%, 0)';
      break;
    case 'top-start':
      // 上左：先往上拉再往左边扩展
      top = referenceRect.top - popperEl.value.offsetHeight - props.popperOffset;
      left = referenceRect.left - popperEl.value.offsetWidth / 2; // 往左扩展
      style.transform = 'translate(-50%, 0)';
      break;
    case 'top-end':
      // 右上：先往右边扩展再往上拉
      top = referenceRect.top - popperEl.value.offsetHeight - props.popperOffset;
      left = referenceRect.right + popperEl.value.offsetWidth / 2; // 往右扩展
      style.transform = 'translate(-50%, 0)';
      break;
    case 'bottom':
      top = referenceRect.bottom + props.popperOffset;
      left = referenceRect.left + referenceRect.width / 2;
      style.transform = 'translate(-50%, 0)';
      break;
    case 'bottom-start':
      top = referenceRect.bottom + props.popperOffset;
      left = referenceRect.left;
      break;
    case 'bottom-end':
      top = referenceRect.bottom + props.popperOffset;
      left = referenceRect.right;
      style.transform = 'translate(-100%, 0)';
      break;
    case 'left':
      top = referenceRect.top + referenceRect.height / 2;
      left = referenceRect.left - props.popperOffset;
      style.transform = 'translate(0, -50%)';
      break;
    case 'left-start':
      top = referenceRect.top;
      left = referenceRect.left - props.popperOffset;
      break;
    case 'left-end':
      top = referenceRect.bottom;
      left = referenceRect.left - props.popperOffset;
      style.transform = 'translate(0, -100%)';
      break;
    case 'right':
      top = referenceRect.top + referenceRect.height / 2;
      left = referenceRect.right + props.popperOffset;
      style.transform = 'translate(0, -50%)';
      break;
    case 'right-start':
      top = referenceRect.top;
      left = referenceRect.right + props.popperOffset;
      break;
    case 'right-end':
      top = referenceRect.bottom;
      left = referenceRect.right + props.popperOffset;
      style.transform = 'translate(0, -100%)';
      break;
  }

  style.position = 'fixed';
  style.top = `${top}px`;
  style.left = `${left}px`;

  return style;
});

// 方法
const handleKeydown = (event: KeyboardEvent) => {
  if (event.key === 'Escape' && popperVisible.value) {
    hidePopper();
  }
};

// 处理子菜单展开/收起
const toggleSubmenu = (index: number) => {
  if (expandedSubmenuIndex.value === index) {
    expandedSubmenuIndex.value = null;
  } else {
    expandedSubmenuIndex.value = index;
  }
};

// 处理菜单项点击事件
const handleItemClick = (item: TuiDropdownItemData) => {
  if (item.disabled) return;

  // 发出select事件，优先使用command值，如果没有则使用item本身
  emit('select', item.command !== undefined ? item.command : item);

  // 点击菜单项后关闭下拉菜单
  if (props.closeOnClickInside) {
    hidePopper();
  }
};

// 重置展开的子菜单
const resetExpandedSubmenu = () => {
  expandedSubmenuIndex.value = null;
};

const handleReferenceClick = (event: MouseEvent) => {
  if (props.disabled) return;

  if (props.trigger === 'click') {
    if (popperVisible.value) {
      hidePopper();
    } else {
      showPopper();
    }
  }
};

const handleContextmenu = (event: MouseEvent) => {
  if (props.disabled) return;

  if (props.trigger === 'contextmenu') {
    event.preventDefault();
    if (popperVisible.value) {
      hidePopper();
    } else {
      showPopper();
    }
  }
};

const handleMouseEnter = () => {
  if (props.disabled) return;

  if (props.trigger === 'hover') {
    clearTimeout(hideTimer.value);
    showTimer.value = window.setTimeout(() => {
      showPopper();
    }, props.showTimeout);
  }
};

const handleMouseLeave = () => {
  if (props.disabled) return;

  if (props.trigger === 'hover') {
    clearTimeout(showTimer.value);
    hideTimer.value = window.setTimeout(() => {
      hidePopper();
    }, props.hideTimeout);
  }
};

const handlePopperClick = (event: MouseEvent) => {
  event.stopPropagation();

  if (props.closeOnClickInside) {
    hidePopper();
  }
};

const handlePopperMouseEnter = () => {
  if (props.disabled) return;

  if (props.trigger === 'hover') {
    clearTimeout(hideTimer.value);
  }
};

const handlePopperMouseLeave = () => {
  if (props.disabled) return;

  if (props.trigger === 'hover') {
    clearTimeout(showTimer.value);
    hideTimer.value = window.setTimeout(() => {
      hidePopper();
    }, props.hideTimeout);
  }
};

const showPopper = () => {
  if (props.disabled || popperVisible.value) return;

  popperVisible.value = true;
  emit('show');
  emit('visible-change', true);
  emit('update:modelValue', true);

  // 添加点击外部关闭事件
  if (props.closeOnClickOutside) {
    nextTick(() => {
      document.addEventListener('click', handleClickOutside);
    });
  }
};

const hidePopper = () => {
  if (!popperVisible.value) return;

  popperVisible.value = false;
  resetExpandedSubmenu(); // 隐藏时重置展开的子菜单
  emit('hide');
  emit('visible-change', false);
  emit('update:modelValue', false);

  // 移除点击外部关闭事件
  if (props.closeOnClickOutside) {
    document.removeEventListener('click', handleClickOutside);
  }
};

const handleClickOutside = (event: MouseEvent) => {
  if (!popperEl.value || !referenceEl.value) return;

  const popperContains = popperEl.value.contains(event.target as Node);
  const referenceContains = referenceEl.value.contains(event.target as Node);

  if (!popperContains && !referenceContains) {
    hidePopper();
  }
};

// 处理菜单项选择（兼容旧版本API）
const handleSelect = (value: any) => {
  emit('select', value);
  hidePopper();
};

// 监听属性变化
watch(() => props.modelValue, (newValue) => {
  if (isMounted.value) {
    if (newValue && !popperVisible.value) {
      showPopper();
    } else if (!newValue && popperVisible.value) {
      hidePopper();
    }
  }
});

watch(() => props.showPopper, (newValue) => {
  if (isMounted.value) {
    if (newValue && !popperVisible.value) {
      showPopper();
    } else if (!newValue && popperVisible.value) {
      hidePopper();
    }
  }
});

// 生命周期
onMounted(() => {
  isMounted.value = true;

  if (props.showPopper || props.modelValue) {
    showPopper();
  }
});

onUnmounted(() => {
  clearTimeout(showTimer.value);
  clearTimeout(hideTimer.value);

  if (props.closeOnClickOutside) {
    document.removeEventListener('click', handleClickOutside);
  }
});

// 提供给子组件的方法
defineExpose({
  showPopper,
  hidePopper,
  handleItemClick
});
</script>

<style lang="scss" scoped>
.tui-dropdown {
  position: relative;
  display: inline-block;
  vertical-align: middle;

  &--disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  &__reference {
    position: relative;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  &__popper {
    position: fixed;
    z-index: 2050;
    background-color: #ffffff;
    border: 1px solid #e4e7ed;
    border-radius: var(--tui-border-radius-default);
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    min-width: 100px;
    max-width: 500px;
    overflow: hidden;

    &--top {
      transform-origin: center bottom;
    }

    &--top-start {
      transform-origin: left bottom;
    }

    &--top-end {
      transform-origin: right bottom;
    }

    &--bottom {
      transform-origin: center top;
    }

    &--bottom-start {
      transform-origin: left top;
    }

    &--bottom-end {
      transform-origin: right top;
    }

    &--left {
      transform-origin: right center;
    }

    &--left-start {
      transform-origin: right top;
    }

    &--left-end {
      transform-origin: right bottom;
    }

    &--right {
      transform-origin: left center;
    }

    &--right-start {
      transform-origin: left top;
    }

    &--right-end {
      transform-origin: left bottom;
    }

    // 尺寸样式
    &--large .tui-dropdown__menu-item {
      padding: 12px 16px;
      font-size: 16px;
    }

    &--default .tui-dropdown__menu-item {
      padding: 8px 16px;
      font-size: 14px;
    }

    &--small .tui-dropdown__menu-item {
      padding: 6px 12px;
      font-size: 12px;
    }
  }

  // 菜单样式
  &__menu {
    width: 100%;
  }

  // 菜单项样式
  &__menu-item {
    display: flex;
    align-items: center;
    padding: 8px 16px;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.2s;
    position: relative;
    font-size: 14px;

    &:hover:not(.is-disabled) {
      background-color: var(--tui-bg-color-light, #f5f7fa);
    }

    &.is-disabled {
      color: var(--tui-text-color-placeholder, #909399);
      cursor: not-allowed;
    }

    &-icon {
      margin-right: 8px;
      font-size: inherit;
    }

    &-label {
      flex: 1;
    }
  }

  // 分组标题样式
  &__menu-group-title {
    padding: 4px 16px;
    color: var(--tui-text-color-secondary, #606266);
    font-size: 12px;
    line-height: 1.5;
  }

  // 子菜单样式
  &__submenu-wrapper {
    position: relative;
  }

  &__submenu-title {
    display: flex;
    align-items: center;
    padding: 8px 16px;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.2s;
    position: relative;
    font-size: 14px;

    &:hover {
      background-color: var(--tui-bg-color-light, #f5f7fa);
    }
  }

  &__submenu-arrow {
    margin-left: auto;
    transition: transform 0.2s;

    &.is-expanded {
      transform: rotate(90deg);
    }
  }

  &__submenu {
    background-color: var(--tui-bg-color-light, #f5f7fa);

    .tui-dropdown__menu-item {
      padding-left: 24px;
    }
  }
}
</style>